package com.pig4cloud.pigx.user.wallet;

import cn.hutool.crypto.symmetric.AES;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pig4cloud.pigx.common.customize.enums.CommonDictEnum;
import com.pig4cloud.pigx.common.customize.redis.constants.RedisKeyEnum;
import com.pig4cloud.pigx.common.customize.redis.utils.RedisUtils;
import com.pig4cloud.pigx.user.constant.WalletConstant;
import com.pig4cloud.pigx.user.entity.Currency;
import com.pig4cloud.pigx.user.entity.RechargeRecord;
import com.pig4cloud.pigx.user.entity.TimingConfig;
import com.pig4cloud.pigx.user.enums.TimingConfigEnums;
import com.pig4cloud.pigx.user.enums.UserEnums;
import com.pig4cloud.pigx.user.service.CurrencyService;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.tron.trident.core.ApiWrapper;
import org.tron.trident.proto.Chain;
import org.tron.trident.proto.Response;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.utils.Convert;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 用户充值时发送手续费
 */
@Component
@AllArgsConstructor
public class SendServiceCharge {

	private final CurrencyService currencyService;

	private final static BigDecimal ETH_FEE = new BigDecimal("0.001");

	private final static BigDecimal TRON_FEE = new BigDecimal("30");
	private final RedisUtils redisUtils;

	/**
	 * 波场发送手续费
	 * @param record 充值记录信息
	 */
	public void tronFee(RechargeRecord record){
		try {
			TimingConfig config = redisUtils.getPersistentCache(RedisKeyEnum.TIMING_CONFIG, TimingConfigEnums.Type.TRON_SERVICE_CHARGE.getValue(), TimingConfig.class);
			AES aes = new AES(WalletConstant.AES_KEY);
			// 解密私钥
			String decryptStr = aes.decryptStr(config.getPrivateKey());
			// 主网
			Currency currency = currencyService.getCurrency(WalletConstant.USDT,UserEnums.Chain.TRON.getValue());
			ApiWrapper wrapper = ApiWrapper.ofMainnet(decryptStr, currency.getApiKey());
			// 测试网
//			ApiWrapper wrapper = ApiWrapper.ofNile(decryptStr);

			// 手续费账户 TRX 余额
			Response.Account account = wrapper.getAccount(config.getAddress());
			BigDecimal decimal = BigDecimal.valueOf(account.getBalance()).divide(new BigDecimal("1000000"),6, RoundingMode.DOWN);

			// 充值用户 TRX 余额
			Response.Account userAccount = wrapper.getAccount(record.getArrivalAddress());
			BigDecimal userDecimal = BigDecimal.valueOf(userAccount.getBalance()).divide(new BigDecimal("1000000"),6, RoundingMode.DOWN);

			// 如果用户trx余额不足10 且 手续费账户有足够trx 则给用户拨款
			if (userDecimal.compareTo(TRON_FEE) < 0 && decimal.compareTo(TRON_FEE.subtract(userDecimal)) >= 0) {
				BigDecimal subtract = TRON_FEE.subtract(userDecimal).multiply(new BigDecimal("1000000"));

				Response.TransactionExtention transfer = wrapper.transfer(
						config.getAddress(),
						record.getArrivalAddress(),
						subtract.longValue()
				);
				Chain.Transaction transaction = wrapper.signTransaction(transfer);
				wrapper.broadcastTransaction(transaction);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * 以太坊发送手续费
	 * @param record 充值记录信息
	 */
	public void bscFee(RechargeRecord record) {
		try {
			// 获取UNT 币种
			Currency currency = currencyService.getOne(new LambdaQueryWrapper<Currency>()
					.eq(Currency::getPublicChain, UserEnums.Chain.BSC.getValue())
					.eq(Currency::getName, WalletConstant.USDT)
					.eq(Currency::getState, CommonDictEnum.Status.NORMAL.getValue())
			);
			TimingConfig config = redisUtils.getPersistentCache(RedisKeyEnum.TIMING_CONFIG, TimingConfigEnums.Type.BSC_SERVICE_CHARGE.getValue(), TimingConfig.class);
			// 查询手续费usc余额
			Web3j web3j = Web3j.build(new HttpService(currency.getNodeAddress()));
			EthGetBalance send = web3j.ethGetBalance(config.getAddress(), DefaultBlockParameterName.LATEST).send();
			BigDecimal decimal = Convert.fromWei(new BigDecimal(send.getBalance()), Convert.Unit.ETHER);

			// 查询用户usc余额
			EthGetBalance balance = web3j.ethGetBalance(record.getArrivalAddress(), DefaultBlockParameterName.LATEST).send();
			BigDecimal userDecimal = Convert.fromWei(new BigDecimal(balance.getBalance()), Convert.Unit.ETHER);
			// 如果用户usc余额不足0.01 且 手续费账户有足够usc 则给用户拨款
			if (userDecimal.compareTo(ETH_FEE) < 0 && decimal.compareTo(ETH_FEE) >= 0) {
				BigDecimal subtract = ETH_FEE.subtract(userDecimal);
				AES aes = new AES(WalletConstant.AES_KEY);
				String str = aes.decryptStr(config.getPrivateKey());
				Credentials credentials = Credentials.create(str);
				TransactionReceipt receipt = Transfer.sendFunds(
						web3j,
						credentials,
						record.getArrivalAddress(),
						subtract,
						Convert.Unit.ETHER).send();
				receipt.getBlockHash();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
